﻿using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using System.Text;
using Microsoft.CSharp;

namespace InterfaceWeaver.CustomTool
{
    public static class CsharpCodeGeneration
    {
        /// <summary>
        /// Generates the source code.
        /// </summary>
        /// <param name="codeDom">The code DOM.</param>
        /// <returns></returns>
        public static string GenerateSourceCode(this CodeCompileUnit codeDom)
        {
            // Build source code
            var builder = new StringBuilder();
            using (var writer = new StringWriter(builder))
            {
                new CSharpCodeProvider().GenerateCodeFromCompileUnit(codeDom, writer,
                    new CodeGeneratorOptions
                    {
                        BracingStyle = "C",
                        BlankLinesBetweenMembers = true,
                        IndentString = "    ",
                        VerbatimOrder = false
                    });
            }

            // Return the finalized source code
            return builder.ToString();
        }

        /// <summary>
        /// Generates the source code.
        /// </summary>
        /// <param name="expression">The expression.</param>
        /// <returns></returns>
        public static string GenerateSourceCode(this CodeExpression expression)
        {
            // Build source code
            var builder = new StringBuilder();
            using (var writer = new StringWriter(builder))
            {
                new CSharpCodeProvider().GenerateCodeFromExpression(expression, writer,
                    new CodeGeneratorOptions
                    {
                        BracingStyle = "C",
                        BlankLinesBetweenMembers = true,
                        IndentString = "    ",
                        VerbatimOrder = false
                    });
            }

            // Return the finalized source code
            return builder.ToString();
        }

        /// <summary>
        /// Generates the source code.
        /// </summary>
        /// <param name="statment">The statment.</param>
        /// <returns></returns>
        public static string GenerateSourceCode(this CodeStatement statment)
        {
            // Build source code
            var builder = new StringBuilder();
            using (var writer = new StringWriter(builder))
            {
                new CSharpCodeProvider().GenerateCodeFromStatement(statment, writer,
                    new CodeGeneratorOptions
                    {
                        BracingStyle = "C",
                        BlankLinesBetweenMembers = true,
                        IndentString = "    ",
                        VerbatimOrder = false
                    });
            }

            // Return the finalized source code
            return builder.ToString();
        }

        /// <summary>
        /// Generates the source code.
        /// </summary>
        /// <param name="type">The statment.</param>
        /// <returns></returns>
        public static string GenerateSourceCode(this CodeTypeDeclaration type)
        {
            // Build source code
            var builder = new StringBuilder();
            using (var writer = new StringWriter(builder))
            {
                new CSharpCodeProvider().GenerateCodeFromType(type, writer,
                    new CodeGeneratorOptions
                    {
                        BracingStyle = "C",
                        BlankLinesBetweenMembers = true,
                        IndentString = "    ",
                        VerbatimOrder = false
                    });
            }

            // Return the finalized source code
            return builder.ToString();
        }
    }
}
